iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
Modern Web

React進階班,用typescript與jest製作自己的custom hooks庫系列 第 8

[Day 8] 今天來個簡單的練習寫useWindowSize

  • 分享至 

  • xImage
  •  

這個應該十分常見,為了想要做RWD或其他原因,我們需要取得目前瀏覽器的長與寬時:

import { useState, useEffect } from "react";

export function useWindowSize() {
  const [width, setWidth] = useState<number>(window.innerWidth || 0);
  const [height, setHeight] = useState<number>(window.innerHeight || 0);
  useEffect(() => {
    const handleResize = () => {
      setWidth(window.innerWidth);
      setHeight(window.innerHeight);
    };

    window.addEventListener("resize", handleResize);
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  return { height, width };
}

但是會有問題,如果是在非瀏覽器環境,例如:SSR,就會因為window未定義的關係跳錯誤,所以我們如果要兼容到nextjs這種SSR的話,就要改成這樣來判斷

import { useState, useEffect } from "react";

export function useWindowSize() {
  const isClient = typeof window === "object";

  const [width, setWidth] = useState<number>(isClient ? window.innerWidth : 0);
  const [height, setHeight] = useState<number>(
    isClient ? window.innerHeight : 0
  );

  useEffect(() => {
    if (!isClient) return;
    const handleResize = () => {
      setWidth(window.innerWidth);
      setHeight(window.innerHeight);
    };

    window.addEventListener("resize", handleResize);
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, [isClient]);

  return { height, width };
}

先去判斷有沒有window,沒有window就不會執行,這樣就可以避免SSR的錯誤


上一篇
[Day 7] useFetch測試摟
下一篇
[Day 9] 寫useWindowSize測試
系列文
React進階班,用typescript與jest製作自己的custom hooks庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言